/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __A_IT_H__
#define __A_IT_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdbool.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_compiler.h>
/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/
/* typedefs ------------------------------------------------------------------*/
/* macro ---------------------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/

/**
 * it_lock - disable irq
 *
 * return: the original primask
 */
static __always_inline unsigned long it_lock(void)
{
    unsigned long flags;

    __asm__ __volatile__(
        "       mrs     %0, primask                                                  \n"
        "       cpsid   i                                                            \n"
        : "=r"(flags)
        :
        : "memory");

    return flags;
}

/**
 * it_unlock - enable irq
 *
 * return: the original primask
 */
static __always_inline unsigned long it_unlock(void)
{
    unsigned long flags;

    __asm__ __volatile__(
        "       mrs     %0, primask                                                  \n"
        "       cpsie   i                                                            \n"
        : "=r"(flags)
        :
        : "memory");

    return flags;
}

/**
 * it_restore - restore primask
 * @flags: the original primask value
 *
 * return: NA
 */
static __always_inline void it_restore(unsigned long flags)
{
    __asm__ __volatile__(
        "       msr     primask, %0                                                  \n"
        :
        : "r"(flags)
        : "memory");
}

/**
 * it_locked - return if interrupt locked
 *
 * return: true or false
 */
static __always_inline bool it_locked(void)
{
    unsigned long flags;

    __asm__ __volatile__(
        "       mrs     %0, primask                                                  \n"
        : "=r"(flags));

    return flags != 0;
}

/**
 * it_context_arch - return if interrupt context
 *
 * return: true or false
 */
static __always_inline bool it_context_arch(void)
{
#if defined(__CC_ARM)
    register uint32_t ipsr __asm("ipsr");
#elif defined(__GNUC__) || defined(__clang__)
    unsigned int ipsr;

    __asm__ __volatile__("mrs %0, ipsr" : "=r"(ipsr));
#else
#error "unsurpported tool!"
#endif

    /* ipsr == 0 means thread mode, otherwise means handler mode */
    return ipsr != 0;
}

/* externs -------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __A_IT_H__ */
